package org.grayrabbit.cms;

import java.util.List;

import org.grayrabbit.cms.extension.Startable;
import org.grayrabbit.cms.plugin.CmsModuleDescriptorFactory;
import org.grayrabbit.cms.plugin.CmsPluginManager;
import org.grayrabbit.cms.plugin.CmsPluginStateStore;
import org.grayrabbit.cms.plugin.DefaultPluginInstallationManager;
import org.grayrabbit.cms.plugin.DefaultPluginLoaderFactory;
import org.grayrabbit.cms.plugin.ModuleDescriptorFactory;
import org.grayrabbit.cms.plugin.PluginInstallationManager;
import org.grayrabbit.cms.plugin.PluginLoaderFactory;
import org.grayrabbit.cms.plugin.PluginManager;
import org.grayrabbit.cms.plugin.PluginStateStore;
import org.grayrabbit.cms.plugin.servlet.PluginResourceDownload;
import org.grayrabbit.cms.properties.ApplicationProperties;
import org.grayrabbit.cms.properties.ApplicationPropertiesImpl;
import org.grayrabbit.cms.propertyset.CmsPropertySetFactory;
import org.grayrabbit.cms.propertyset.DefaultCmsPropertySetFactory;
import org.picocontainer.DefaultPicoContainer;
import org.picocontainer.PicoContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * @author sys53
 * @version 1.0
 * @created 06-01-2012 13:00:34
 */
public class ComponentManager {
	private static final Logger log = LoggerFactory.getLogger(ComponentManager.class);
	private static final ComponentManager COMPONENT_MANAGER = new ComponentManager();
	private DefaultPicoContainer internalContainer;
	private PicoContainer container;

	private ComponentManager(){
		try{
			initialise();
		}catch(Exception e){
			log.error("ComponentManager初始化时发生错误，Cms不能正常启动。",e);
		}
	}

	public void eagerlyInstantiate(){

	}

	public PicoContainer getContainer(){
		return this.container;
	}

	public static ComponentManager getInstance(){
		return COMPONENT_MANAGER;
	}

	public PluginManager getPluginManager(){
		return null;
	}
	/**
	 * 初始化
	 */
	public void initialise(){
		registerComponents();
		registerExtensions();
	}
	//注册扩展组件
	private void registerExtensions() {
		this.container = this.internalContainer;
		
	}
	//注册组件
	private void registerComponents() {
		this.internalContainer = new DefaultPicoContainer();
		this.internalContainer.addComponent(ApplicationProperties.class,ApplicationPropertiesImpl.class);
		this.internalContainer.addComponent(PluginLoaderFactory.class,DefaultPluginLoaderFactory.class);
		this.internalContainer.addComponent(PluginManager.class,CmsPluginManager.class);
		this.internalContainer.addComponent(PluginStateStore.class,CmsPluginStateStore.class);
		this.internalContainer.addComponent(PluginInstallationManager.class,DefaultPluginInstallationManager.class);
		this.internalContainer.addComponent(ModuleDescriptorFactory.class, CmsModuleDescriptorFactory.class);
		this.internalContainer.addComponent(CmsPropertySetFactory.class, DefaultCmsPropertySetFactory.class);
		this.internalContainer.addComponent(PluginResourceDownload.class);
		
	}

	public synchronized void start(){
		quickStart();
	}

	private void quickStart() {
		PluginManager pluginManager = this.container.getComponent(PluginManager.class);
		if(pluginManager instanceof Startable){
			Startable startablePluginManager = (Startable) pluginManager;
			try{
				startablePluginManager.start();
			}catch(Exception e){
				log.error("PluginManager组件启时发生错误",e);
				throw new IllegalArgumentException("PluginManager组件时发生错误",e);
			}
		}else{
			log.error("可启动组件启动时发生错误");
			throw new IllegalArgumentException("启动组件时发生错误");
		}
		
		List<Startable> startableCompents = this.getContainer().getComponents(Startable.class);
		if(startableCompents!=null){
			try{
				for(Startable sc :startableCompents ){
					if(! (sc instanceof PluginManager)){
						sc.start();
					}
				}
			}catch(Exception e){
				log.error("可启动组件启j时发生错误",e);
				throw new IllegalArgumentException("启动组件时发生错误",e);
			}
		}
	}

	public ApplicationProperties getApplicationProperties() {
		return getContainer().getComponent(ApplicationProperties.class);
		
	}

}